docs(spec): name the mis-aimed group case in navigationContributions[].group - #16508
Conversation
…].group The describe() documented only the omitted case. Name the third case an author cannot detect from their own source: the contributing package does not see the target app's group ids, so a wrong id is not refused -- the items are appended at the app top level and a nav_contribution_group_missing diagnostic is emitted, by the runtime at warn and by os build and os validate at compile time. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01T6HeZvT9wdSJD1ZxJb5Eno
Regenerated with the repo's own tooling (pnpm --filter @objectstack/spec gen:schema && ... gen:docs); the two tracked reference tables are the only tracked artifacts that move. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01T6HeZvT9wdSJD1ZxJb5Eno
📓 Docs Drift CheckThis PR changes 1 package(s): 1 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:
What this run could not see
Coarse fallback — 130 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): Which tree this was computed onThis run read A worktree cut from an older # while this PR is open — GitHub drops the merge commit once it closes
git fetch origin a0e6a3f1a14248d993d1211d281820fc2db0eabe && git checkout a0e6a3f1a14248d993d1211d281820fc2db0eabe
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin c383352cb752245899b6ca7e2dc7d233405113ee 049daaeaa23e6fe56e87d281913c40a23402030d && git checkout -B drift-repro c383352cb752245899b6ca7e2dc7d233405113ee && git merge --no-ff 049daaeaa23e6fe56e87d281913c40a23402030d
node scripts/docs-audit/affected-docs.mjs --json c383352cb752245899b6ca7e2dc7d233405113ee
|
Fixes #14925
The
describe()onnavigationContributions[].groupwas true and incomplete: it documented the omitted case and said nothing aboutgroupbeing present and naming no group the target app declares — the case that actually bites, because the contributing package cannot see the target app's group ids at authoring time (the target app belongs to another package). A wrong id is undetectable from the contributor's own source, and the platform relocates the items to the app top level rather than refusing them, so the menu renders, a smoke test passes, and the information architecture has silently changed.The line, located by symbol
Re-located by symbol as instructed rather than trusted from the card:
NavigationContributionSchema'sgroupproperty inpackages/spec/src/ui/app.zod.ts. It is still at:764— the anchor had not drifted.Final wording
Four decisions behind it:
nav_contribution_group_missingin build output can search back to the key that produced it.os buildwould have been wrong against what shipped — see below.|would break both rows.Verification of the two corrections in comment 5525508353 — checked against the tree, not inherited
①
os validatereports the diagnostic too. CONFIRMED.findNavGroupDiagnosticshas exactly two non-test call sites, and they are the two commands:packages/cli/src/commands/compile.ts:49andpackages/cli/src/commands/validate.ts:43. Each folds the result into its ownwarningslist —compile.ts:202,validate.ts:148— rather than into a key of its own.validate.ts:130carries the reason in-source: the residue pin "asserts that nothing rides in build'swarningsthat validate does not also report".② A top-level
navigationGroupDiagnosticskey does not exist. CONFIRMED.git grep navigationGroupDiagnosticsreturns exactly one hit repo-wide, and it is prose, not code:packages/cli/src/utils/nav-contribution-groups.ts:46, in a doc block explaining that the first cut carried such a key and that two standing pins (build-json-advisory-parity.e2e.test.ts,build-json-undeclared-key-parity.e2e.test.ts, both present inpackages/cli/test/) rejected it. No schema, no payload, no emitter. Nothing here describes it.Regeneration — the command, and the count actually measured
⛔ No generated artifact was hand-edited.
Measured, not repeated from the card. The card estimated "~14 artifacts"; the measurement says 26 carriers, and they split in a way worth stating because only one half is reviewable in this diff:
git diff --name-onlygrep -rl "Naming a group the target app does not declare" content/docs packages/spec/json-schemaThe 24 that are not in the diff are the
packages/spec/json-schema/tree, which.gitignore:63excludes — built on demand, not committed. They are 12json-schema/api/*.jsonand 10json-schema/kernel/*.jsonpackage envelopes, the bundledjson-schema/objectstack.json, andjson-schema/ui/NavigationContribution.jsonitself. So the card's "~11 api envelopes" undercounted, and its list omitted thekernel/envelopes entirely.The two tracked files are
content/docs/references/ui/app.mdxandcontent/docs/references/kernel/manifest.mdx, one table row each.Clause ② reads NO — confirmed mechanically, and the gate was proved able to say otherwise
Prose on an existing key.
groupis stillSnakeCaseIdentifierSchema.optional(); nothing is refused that was not refused before.pnpm --filter @objectstack/spec check:api-surface— exit 0, verdict line:@objectstack/spec public API surface + factory signatures unchanged ✓pnpm --filter @objectstack/spec check:authorable-surface— exit 0, andauthorable-surface.jsonplusjson-schema.manifest.jsonare byte-identical to base (the regeneration left them untouched; only the two.mdxfiles appear ingit status).A silent green is not a reading, so the second gate was ablated at the committed state to show it can go red on exactly this axis. One new authorable key injected into the same schema (
groupFallback), proved on disk (injected-text count 1,git hash-objectdiffering from theHEADblob), produced:Restored with
git checkout HEAD -- packages/spec/src/ui/app.zod.ts, proved by an emptygit diff HEAD, and the gitignored schema tree regenerated afterwards so no probe residue survives (grep -rl "ABLATION PROBE" packages/spec/json-schema/returns nothing, while the real sentence still returns its 24 files — the positive control for that zero).Gates and tests
Derived with
node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack(change set: 4 paths vs merge base21c5dcbb3) — 90 commands, 89 green. Every exit code captured before any pipe.pnpm --filter '@objectstack/spec...' build— exit 0 (check-dts-emitted: 34/34)pnpm --filter @objectstack/spec typecheck— exit 0pnpm --filter @objectstack/spec test— exit 0, 482 files / 13102 tests passedcheck:docs— exit 0,228 generated files in sync with packages/spec. Ablated too: reverting only the two regenerated.mdxfiles to base makes it exit 1, naming both files "out of date" — so its green here is a measurement of this regeneration and not of an untested gate.PREREQUISITE NOT METfor unbuilt packages, which is NOT MEASURED rather than red. Four were cleared by building@objectstack/lint,@objectstack/formula,@objectstack/client,@objectstack/client-reactand re-running:check:doc-formula-expressions,check:doc-security-posture,check:skill-examples,check:docs-transcript-drift— all exit 0.pnpm check:dual-build-cjs-loadsneeds a full-repodist/(it named 86 unbuilt packages) and stays NOT MEASURED here — a whole-workspace build does not fit this container's foreground budget. It reads emitted CJS loadability; this diff is one string literal inside a.describe(), two generated markdown table rows and a changeset, and moves no package's exports map or build shape. Left to CI.Verdicts, logs and the two ablation transcripts are in the report comment on #14925.
Changeset
.changeset/nav-contribution-group-mis-aim-describe.md,@objectstack/spec: patch. Patch is the level: the published JSON Schemadescriptionfor an existing key changes and the generated reference rows change, so it is user-visible and needs an entry — but no key is added or removed, no type moves, and no runtime behaviour changes, which is what would have made itminor.Out of scope
navigationContributions[].groupare incomplete against what #14920 shipped #16507: two source comments carrying the same incompleteness — theNavigationContributionSchemaJSDoc just above this key still names only the omitted case, andexamples/app-multi-package/src/packages/orders/index.ts:47still names onlyos build. Neither reaches a generated artifact (verified bygit grep), and the example lives in another package, so folding them in would widen this PR past the regeneration family it was sized for.navigationContributions[].groupthat names no group in the target app is silently RELOCATED to the top level — refuse, warn, or leave to the consumer? #14553 is not addressed here and remains open on its own terms. The diagnostic itself is fix(objectql,cli): a navigation contribution relocated past a missing group now says so, atwarnand at build time #14920, already landed and untouched.Generated by Claude Code